package com.baizhi.service.impl;

import com.baizhi.dto.request.TeacherDTO;
import com.baizhi.dto.response.StudentDTO;
import com.baizhi.entity.*;
import com.baizhi.exception.CodeEnum;
import com.baizhi.mapper.BacklogMapper;
import com.baizhi.mapper.CourseMapper;
import com.baizhi.mapper.TeacherMapper;
import com.baizhi.service.TeacherService;
import com.baizhi.service.UserService;
import com.baizhi.utils.MD5Util;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
* @author 16357
* @description 针对表【t_teacher】的数据库操作Service实现
* @createDate 2024-08-14 09:43:07
*/
@Service
public class TeacherServiceImpl extends ServiceImpl<TeacherMapper, Teacher>
    implements TeacherService{

    @Autowired
    private UserService userService;

    @Autowired
    private CourseMapper courseMapper;

    @Autowired
    private TeacherMapper teacherMapper;

    @Autowired
    private BacklogMapper backlogMapper;

    @Override
    @Transactional
    public Boolean logOutTeacher(Integer userId) {
        // 通过userID获取stuId
        //获取学生ID
        QueryWrapper<Teacher> wrapper = new QueryWrapper<>();
        wrapper.eq("user_id",userId).select("pk_tid");
        Integer teacherId = teacherMapper.selectOne(wrapper).getPkTid();

        //教师注销需要删除哪些表中的数据？
        //删除t_user ,得先保证t_user这种有userId
        Optional<User> userOptional = Optional.ofNullable(userService.getById(userId));
        if(userOptional.isPresent()){
           boolean userFlag = userService.removeById(userId);
            if(!userFlag){
                CodeEnum.user_logout_fail.throwException();
            }
        }
        //删除t_teacher

        Optional<Teacher> teacherOptional = Optional.ofNullable(teacherMapper.selectById(teacherId));

        if(teacherOptional.isPresent()){
            int teacherRow = teacherMapper.deleteById(teacherId);
            if(teacherRow == 0){
                CodeEnum.user_logout_fail.throwException();
            }
        }

        //删除 t_backlog //根据user_id删除
        QueryWrapper<Backlog> backlogQueryWrapper = new QueryWrapper<>();
        backlogQueryWrapper.eq("user_id", userId);

        Optional<Backlog> backlogOptional = Optional.ofNullable(backlogMapper.selectOne(backlogQueryWrapper));

        if(backlogOptional.isPresent()){
           int backlogRow = backlogMapper.delete(backlogQueryWrapper);
            if(backlogRow == 0){
                CodeEnum.user_logout_fail.throwException();
            }
        }


        //修改t_course中的teacher_id 为 null
        // 修改t_course中的teacher_id 为 null
        QueryWrapper<Course> courseQueryWrapper = new QueryWrapper<>();
        courseQueryWrapper.eq("teacher_id", teacherId);

        List<Course> courses = courseMapper.selectList(courseQueryWrapper);

        if (!courses.isEmpty()) {
            Course course = new Course();
            course.setGmtModified(new Date());
            course.setTeacherId(-1);


            int courseRow = courseMapper.update(course, courseQueryWrapper);
            if (courseRow == 0) {
                CodeEnum.user_logout_fail.throwException();
            }
        }

        return true;
    }


    @Override
    @Transactional
    public boolean updateTeacher(User user) {
        //1. 判断用户是否存在
        User result = userService.getById(user.getPkUid());
        if(result == null){
            CodeEnum.user_is_no_regist.throwException(); //用户未注册
        }
        //2. 判断用户数据是否进行了更新，如果没有更新则抛出异常
        //用户名，姓名，性别 联系电话，地址 不能为null
        if(user.getUserName() == null || user.getRealName() == null || user.getSex() == null || user.getPhone() == null || user.getAddress()==null){
            CodeEnum.update_userdata_not_is_null.throwException(); //用户修改的数据不能为空
        }
        //判断数据是否进行了更新
        boolean flag = Objects.equals(user.getUserName(),result.getUserName())
                && Objects.equals(user.getRealName(),result.getRealName())
                && Objects.equals(user.getSex(),result.getSex())
                && Objects.equals(user.getPhone(),result.getPhone())
                && Objects.equals(user.getAddress(),result.getAddress());



        if(flag){ //表示数据没有变化
            CodeEnum.userdata_not_update.throwException();
        }

        //3. 进行修改
        //修改user表
        result.setUserName(user.getUserName());
        result.setRealName(user.getRealName());
        result.setSex(user.getSex());
        result.setPassword(user.getPassword());
        result.setAddress(user.getAddress());
        result.setGmtModified(new Date());

        boolean b1 = userService.updateById(result); //修改User表

        //修改教师表
        //查找教师ID，根据教师ID修改教师表
        QueryWrapper<Teacher> wrapper = new QueryWrapper<>();
        wrapper.eq("user_id",user.getPkUid()).select("pk_tid");
        Teacher t = teacherMapper.selectOne(wrapper);

        if(t == null){
            CodeEnum.teacher_not_fond.throwException(); //教师数据不存在
        }
        Teacher teacher = new Teacher();
        teacher.setPkTid(t.getPkTid());
        teacher.setName(result.getRealName());
        teacher.setSex(result.getSex());
        teacher.setPhone(result.getPhone());
        teacher.setAddress(result.getAddress());
        teacher.setGmtModified(new Date());

        int row = teacherMapper.updateById(teacher);

        if(!b1 || row==0 ){
            CodeEnum.user_update_fail.throwException(); //数据修改失败
        }


        return true;
    }

    @Override
    public Integer updateScoreByStuIdAndCourseId(Integer stuId, Integer courseId, Integer score) {
        //1. 验证要修改的数据是否存在
        StudentCourse studentCourse = courseMapper.queryCourseByStudentIdAndCourseId(stuId, courseId);
        if(studentCourse == null){
            //要修改数据不存在
            CodeEnum.update_score_is_not_exist.throwException();
        }
        Integer row = teacherMapper.updateScoreByStuIdAndCourseId(stuId, courseId, score);
        if(row == 0){
            CodeEnum.update_score_is_fail.throwException(); //成绩修改失败
        }
        return row;
    }

    @Override
    public Integer deleteMyCourseByUserIdAndCourseId(Integer stuId, Integer courseId) {

        Integer row = courseMapper.deleteMyCourseByStuIdAndCourseId(stuId, courseId);
        if(row == 0){
            CodeEnum.cancel_a_course_fail.throwException(); //取消选课失败
        }
        return row;
    }


    @Override
    public List<StudentDTO> getStudentsByCourseId(Integer courseId) {
        //验证课程ID不为空
        Optional<Course> optionalCourse = Optional.ofNullable(courseMapper.selectById(courseId));
        if(!optionalCourse.isPresent()){
            CodeEnum.course_is_not_exit.throwException(); //课程不存在异常
        }
        List<StudentDTO> list = teacherMapper.queryStudentsByCourseId(courseId);
        if(list==null || list.isEmpty()){
            CodeEnum.no_student_selected_course.throwException(); //没有学生选择该门课程
        }

        return list;
    }

    @Override
    @Transactional
    public void teacherRegist(TeacherDTO teacherDTO) {
        //1. 通过teacherDTO获取 userName
        String userName = teacherDTO.getUsername();
        //2. 通过userName查询用户名是否存在，查询结果是一个user
        User user = userService.getUserByUserName(userName);
        //3. 如果存在(user!=null)，抛出用户名被占用异常，已经存在，无需另外规划
        if(user!=null){
            CodeEnum.username_already_exist.throwException(); //用户名被占用
        }
        //4. 生成盐值，密码加密
        String password = teacherDTO.getPassword();
        String salt = UUID.randomUUID().toString().toUpperCase(Locale.ROOT);
        String md5Password = MD5Util.getMd5Password(password, salt);
        //5. 注册，注册需要往两张表中添加数据，t_user ,t_teacher,需要将teacherDTO拆分成两个对象Teacher和User
        //5.1 补全User属性，注册
        User result = buildUserByTeacherDTO(teacherDTO);
        result.setSalt(salt);
        result.setRoleId(2); //设置角色 教师

        //设置加密后的密码
        result.setPassword(md5Password);


        result.setGmtCreate(new Date());
        result.setGmtModified(new Date());

        boolean uFlag = userService.save(result); //添加用户

        //5.2 补全Teacher属性，注册
        Teacher teacher = buildTeacherByTeacherDTO(teacherDTO);
        teacher.setUserId(result.getPkUid());
        teacher.setGmtCreate(new Date());
        teacher.setGmtModified(new Date());

        boolean tFlag = this.save(teacher);


        //注册失败抛出注册失败异常 已存在，无需另外规划
        if(!uFlag || !tFlag){
            CodeEnum.user_register_fail.throwException(); //注册失败
        }


    }


    /**
     * 通过TeacherDTO构建User对象
     * @return
     */
    private User buildUserByTeacherDTO(TeacherDTO teacherDTO){
        User user = new User();
        user.setUserName(teacherDTO.getUsername());
        user.setPassword(teacherDTO.getPassword());
        user.setRealName(teacherDTO.getRealName());
        user.setPhone(teacherDTO.getPhone());
        user.setSex(teacherDTO.getGender());
        user.setAddress(teacherDTO.getAddress());


        return user;
    }

    /**
     * 通过TeacherDTO构建Teacher对象
     * @return
     */
    private Teacher buildTeacherByTeacherDTO(TeacherDTO teacherDTO){
        Teacher teacher = new Teacher();
        teacher.setName(teacherDTO.getRealName());
        teacher.setPhone(teacherDTO.getPhone());
        teacher.setEmail(teacherDTO.getEmail());
        teacher.setSex(teacherDTO.getGender());
        teacher.setAddress(teacherDTO.getAddress());

        return teacher;
    }

}




